package com.linkgie.galaxyframework.metadata;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 数据引用类型。
 * <p>
 * 
 * 数据引用类型（{@link DataReference}）属于 {@link ContentType} 的一种，标注的字段将生成“引用”类型的内容类型 ({@link ContentType.Reference#TYPE})。
 * <p>
 * 
 * {@link DataReference} 用于对实体类型(标注{@link DataEntity}的类型)中的字段进行标注，并且该字段的类型必须是单值类型（或者单值类型数组），不能是对象类型（对应 {@link StandardType#OBJECT}）。<p>
 * 
 * 逻辑上而言，{@link DataReference} 标注的字段对于 {@link #model()} 参数指定的数据模型类型而言，应该是数据模型类型中的主键字段或者唯一索引字段；<br>
 * 但是框架并不会严格检查其对应关系，目的是提供更多灵活性。应注意的是，如果标注的字段类型不是数据模型类型的主键字段或者唯一索引字段，在应用上没有意义，并且可能会导致数据唯一性错误。
 * 
 * <p>
 * 
 * @author huanghaiquan
 *
 */
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataReference {

	/**
	 * 引用的数据实体的类型(用 {@link DataEntity} 标注)；
	 * 
	 * @return
	 */
	Class<?> model() default void.class;

	/**
	 * 引用的以 {@link DataInterface} 标注的数据接口；<p>
	 * 
	 * 该接口被模型({@link #model()})实现，表达的含义是引用数据模型中的由接口声明的一部分字段的子集；<p>
	 * 
	 * 注： interfase 等同于 interface ，为了规避Java语言关键字而将字母 c 替换为 s ；
	 * 
	 * @return
	 */
	Class<?> interfase() default void.class;
	
//	/**
//	 * 引用的以 {@link DataService} 标注的数据服务类型；<p>
//	 * 
//	 * @return
//	 */
//	Class<?> dataService() default void.class;
	
	/**
	 * 引用的数据范围的查询条件接口；<p>
	 * 
	 * 查询条件接口表达的含义是指定引用数据模型中的一组字段作为查询的维度；
	 * 
	 * @return
	 */
	Class<?> conditionInterface() default void.class;
	
	/**
	 * 值字段；<p>
	 * 
	 * 表示在引用的数据模型中与当前标注字段一起构成引用关系的字段；<p>
	 * 
	 * 在引用的数据模型中，此参数指定的字段通常应是主键字段或者唯一性索引字段；<p>
	 * 
	 * @return
	 */
	String valueKey() default "";
	
	/**
	 * 标签字段；<p>
	 * 
	 * 表示引用的数据模型的在此引用关系中作为字面文字的字段；<p>
	 * 
	 * @return
	 */
	String labelKey() default "";
	
	/**
	 * 级联字段 key ；<p>
	 * 
	 * 引用的数据模型的下一级级联字段；<p>
	 * 
	 * 表示在引用的数据模型中，用于此引用关系进一步级联延伸到下一级的字段；<p>
	 * 
	 * 典型的例子便是“树状”的数据结构；<p>
	 * 
	 * 在引用的数据模型中，一个字段需要满足以下条件之一，才能作为级联字段：<br>
	 * 1. 字段的数据类型是对象类型（{@link StandardType#OBJECT}），具体类型为自身的数据模型；<br>
	 * 2. 字段的数据类型是单值类型，但标注了引用({@link DataReference})或组合({@link DataComposite})或聚（ {@link DataAggregate} 的数据模型为自身的数据模型；
	 * 
	 * <p>
	 * 
	 * 通过指定级联字段，定义对象之间的多层级数据引用关系，并可以生成引用关系的元数据，在此元数据的基础上还可以为 UI 提供自动层级化展开进行交互选择的能力；<p>
	 * 
	 * 注意：声明了级联引用的字段的数据类型必须是整数、字符串类型，因为作为单值类型才能够接受级联选择的引用值；
	 * 
	 * @return
	 */
	String cascadeKey() default "";
	
	/**
	 * 级联分隔符；<p>
	 * 
	 * 表示多个级联引用值之间的分隔符；<p>
	 * 
	 * 默认为： / ；
	 * 
	 * @return
	 */
	@Deprecated
	String cascadeSeperator() default "/";
	
	/**
	 * 当数据类型为对象时，是否仍自动刷新为最新对象；<p>
	 * 
	 * 默认为 false；<p>
	 * 
	 * 如果后端服务不保证返回的字段值所引用的对象是最新的数据，则应该将此选项设置为 true ，前端会根据设置的值字段(valueKey)更新引用对象的其它属性；<p>
	 * 
	 * 注：计划移除此参数；此参数定义了交互呈现的行为，超出了内容类型（ContentType）只定义数据结构形态的设计原则边界；
	 * 
	 * @return
	 */
	@Deprecated
	boolean refreshObjects() default false;
}
